package mx.itesm.rmroman.proyectojuegomavi;

import android.graphics.drawable.shapes.RoundRectShape;
import android.opengl.GLES20;
import android.util.Log;

import org.andengine.audio.music.Music;
import org.andengine.audio.music.MusicFactory;
import org.andengine.audio.sound.SoundFactory;
import org.andengine.engine.camera.Camera;
import org.andengine.entity.IEntityFactory;
import org.andengine.entity.particle.BatchedSpriteParticleSystem;
import org.andengine.entity.particle.ParticleSystem;
import org.andengine.entity.particle.emitter.CircleParticleEmitter;
import org.andengine.entity.particle.emitter.PointParticleEmitter;
import org.andengine.entity.particle.emitter.RectangleParticleEmitter;
import org.andengine.entity.particle.initializer.AccelerationParticleInitializer;
import org.andengine.entity.particle.initializer.AlphaParticleInitializer;
import org.andengine.entity.particle.initializer.BlendFunctionParticleInitializer;
import org.andengine.entity.particle.initializer.ColorParticleInitializer;
import org.andengine.entity.particle.initializer.ExpireParticleInitializer;
import org.andengine.entity.particle.initializer.RotationParticleInitializer;
import org.andengine.entity.particle.initializer.ScaleParticleInitializer;
import org.andengine.entity.particle.initializer.VelocityParticleInitializer;
import org.andengine.entity.particle.modifier.AlphaParticleModifier;
import org.andengine.entity.particle.modifier.RotationParticleModifier;
import org.andengine.entity.particle.modifier.ScaleParticleModifier;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.background.AutoParallaxBackground;
import org.andengine.entity.scene.background.ParallaxBackground;
import org.andengine.entity.scene.background.SpriteBackground;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.sprite.ButtonSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.UncoloredSprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.opengl.util.GLState;

import java.io.IOException;

/**
 * La escena que muestra información del juego
 * @author Roberto Martínez Román
 */
public class EscenaAcercaDe extends EscenaBase
{
    private Sprite spriteFondo; //(el fondo de la escena, estático)
    private ButtonSprite spriteBtnRegreso;    // El botón de BACK sin imagen de 'presionado'
    // Un fondo para el botón regresar
    private Rectangle fondoBtn;

    // ***** MUSICA DE FONDO *****
    private Music musicaFondo;

    @Override
    public void crearEscena() {
        // Creamos el sprite de manera óptima
        spriteFondo = new Sprite(0,0, admRecursos.regionFondoAcercaDe,admRecursos.vbom) {
            @Override
            protected void preDraw(GLState pGLState, Camera pCamera) {
                super.preDraw(pGLState, pCamera);
                pGLState.enableDither();
            }
        };

        // Configuración de la imagen
        spriteFondo.setPosition(ControlJuego.ANCHO_CAMARA/2,ControlJuego.ALTO_CAMARA/2);
        SpriteBackground fondo = new SpriteBackground(0,0,0,spriteFondo);
        setBackground(fondo);
        setBackgroundEnabled(true);

        // Sistema de partículas
        agregarBurbujas();  // Burbujas de jabón
        agregarHumo();      // Humo
        agregarFuego();     // Fuego

        agregarBtnRegreso();    // Para encapsular el manejo del Botón regresar

        // MUSICA
        cargarSonidos();
    }

    // Carga los recursos de sonido
    private void cargarSonidos() {
        // ***** Música de fondo
        try {
            musicaFondo = MusicFactory.createMusicFromAsset(admRecursos.engine.getMusicManager(),
                    admRecursos.actividadJuego, "sonidos/Aeris.ogg");
        }
        catch (IOException e) {
            Log.i("cargarSonidos", "No se puede cargar Aeris.ogg");
        }
        // Reproducir
        musicaFondo.play();
    }

    private void agregarHumo() {

        CircleParticleEmitter circulo = new CircleParticleEmitter(ControlJuego.ANCHO_CAMARA,
                ControlJuego.ALTO_CAMARA/2,10);
        BatchedSpriteParticleSystem sistema = new BatchedSpriteParticleSystem(circulo,
                20, 30, 200, admRecursos.regionHumo, admRecursos.vbom);

        // Velocidad de las partículas minX, maxX, minY, maxY
        sistema.addParticleInitializer(new VelocityParticleInitializer<UncoloredSprite>(-50,-20,-30,30));
        // Aceleración
        sistema.addParticleInitializer(new AccelerationParticleInitializer<UncoloredSprite>(-20,0));

        float tiempoVida = 5;   // Segundos de vida de cada partícula
        // Tiempo para que las partículas expiren.
        sistema.addParticleInitializer(new ExpireParticleInitializer<UncoloredSprite>(tiempoVida));
        // Escala
        sistema.addParticleInitializer(new ScaleParticleInitializer<UncoloredSprite>(0.5f,1.5f));
        // Rotación
        sistema.addParticleModifier(new RotationParticleModifier<UncoloredSprite>(1,4,0,360));
        // Alpha de las partículas, recibe el rango de tiempo y el rango de alpha
        sistema.addParticleModifier(new AlphaParticleModifier<UncoloredSprite>(tiempoVida-2,tiempoVida+1,1,0.3f));

        // Se agrega a la escena, como cualquier Sprite
        attachChild(sistema);
    }

    private void agregarFuego() {

        IEntityFactory<Sprite> ief = new IEntityFactory<Sprite>() {
            @Override
            public Sprite create(float pX, float pY) {
                return new Sprite(pX,pY,admRecursos.regionHumo,admRecursos.vbom);
            }
        };

        PointParticleEmitter punto = new PointParticleEmitter(5*ControlJuego.ANCHO_CAMARA/8,
                0);
        final ParticleSystem<Sprite> sistema = new ParticleSystem<Sprite>(ief,punto,20,50,200);

        sistema.addParticleInitializer(new BlendFunctionParticleInitializer<Sprite>(
                GLES20.GL_SRC_ALPHA,GLES20.GL_ONE));

        sistema.addParticleInitializer(new ColorParticleInitializer<Sprite>(1,0.5f,0));
        sistema.addParticleInitializer(new AlphaParticleInitializer<Sprite>(0));
        sistema.addParticleInitializer(new VelocityParticleInitializer<Sprite>(-15,15,20,90));
        float tiempoVida = 4.5f;   // Segundos de vida de cada partícula
        sistema.addParticleInitializer(new ExpireParticleInitializer<Sprite>(tiempoVida));
        sistema.addParticleInitializer(new ScaleParticleInitializer<Sprite>(0.5f));
        sistema.addParticleInitializer(new RotationParticleInitializer<Sprite>(0, 360));
        sistema.addParticleModifier(new AlphaParticleModifier<Sprite>(0,0.5f,0,0.2f));
        sistema.addParticleModifier(new AlphaParticleModifier<Sprite>(tiempoVida-2,tiempoVida+1,0.2f,0f));
        sistema.addParticleModifier(new ScaleParticleModifier<Sprite>(tiempoVida-2,tiempoVida+1,0.5f,0f));
        sistema.addParticleModifier(new RotationParticleModifier<Sprite>(1,3,0,360));

        // Se agrega a la escena, como cualquier Sprite
        attachChild(sistema);
    }


    private void agregarBurbujas() {

        // El rectángulo de emisión, en esta zona se generan las burbujas
        // El constructor recibe x,y,ancho,alto
        RectangleParticleEmitter zonaEmision = new RectangleParticleEmitter(
                ControlJuego.ANCHO_CAMARA/4,0,
                ControlJuego.ANCHO_CAMARA/2,ControlJuego.ALTO_CAMARA/8);

        // El sistema de partículas, se construye con zona de emisión, rango de partículas emitidas por segundo,
        // máximo número de partículas en la pantalla, región de la imagen y el vertexBuffer
        BatchedSpriteParticleSystem sistema = new BatchedSpriteParticleSystem(
                zonaEmision, 2, 9, 200, admRecursos.regionBurbuja, admRecursos.vbom );

        // Velocidad de las partículas minX, maxX, minY, maxY
        sistema.addParticleInitializer(new VelocityParticleInitializer<UncoloredSprite>(-40,40,50,100));

        float tiempoVida = 6;   // Segundos de vida de cada partícula
        // Tiempo para que las partículas expiren.
        sistema.addParticleInitializer(new ExpireParticleInitializer<UncoloredSprite>(tiempoVida));

        // Alpha de las partículas, recibe el rango de tiempo y el rango de alpha
        sistema.addParticleModifier(new AlphaParticleModifier<UncoloredSprite>(tiempoVida-2,tiempoVida+1,1,0));

        // Se agrega a la escena, como cualquier Sprite
        attachChild(sistema);
    }

    private void agregarBtnRegreso() {
        // Habilita los eventos de touch en ciertas áreas
        setTouchAreaBindingOnActionDownEnabled(true);

        float posicionX = admRecursos.regionBtnRegresar.getWidth()/2;
        float posicionY = admRecursos.regionBtnRegresar.getHeight()/2;
        spriteBtnRegreso = new ButtonSprite(posicionX,posicionY,admRecursos.regionBtnRegresar,
                admRecursos.vbom) {
            @Override
            public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {

                if (pSceneTouchEvent.isActionUp()) {
                    onBackKeyPressed();
                }
                return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY);
            }
        };

        // Registra el área del botón
        registerTouchArea(spriteBtnRegreso);

        // Crea el cuadro detras del botón de regresar
        fondoBtn = new Rectangle(posicionX,posicionY,128,128,admRecursos.vbom) {
            // Este método se ejecuta cada vez que se actualiza el juego (fps)
            @Override
            protected void onManagedUpdate(float pSecondsElapsed) {
                super.onManagedUpdate(pSecondsElapsed);
                // El parámetro nos indica el tiempo entre llamadas
                // Se usa para que la velocidad sea independiente del CPU
                //fondoBtn.setRotation(fondoBtn.getRotation()+100*pSecondsElapsed);
                fondoBtn.setWidth( ((int)fondoBtn.getWidth()+1)%128 ) ;
            }
        };

        fondoBtn.setColor(0,0,0,0.4f);  // Negro con 40% de opacidad
        attachChild(fondoBtn);

        // Agrega el botón de regreso después del fondo
        attachChild(spriteBtnRegreso);
    }

    // El usuario oprime el botón de BACK; regresar al menú principal
    @Override
    public void onBackKeyPressed() {
        // Regresar al MENU principal
        musicaFondo.stop();
        admEscenas.crearEscenaMenu();
        admEscenas.setEscena(TipoEscena.ESCENA_MENU);
        admEscenas.liberarEscenaAcercaDe();
    }

    @Override
    public TipoEscena getTipoEscena() {
        return TipoEscena.ESCENA_ACERCA_DE;
    }

    @Override
    public void liberarEscena() {
        musicaFondo.release();
        this.detachSelf();      // La escena misma se deconecta del engine
        this.dispose();         // Libera la memoria
    }

    public Music getMusicaFondo() {
        return musicaFondo;
    }
}
